package swingExtended.swingControlGroup;

import com.google.common.io.Files;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import processorIO.FileIO;
import tuples.Pair;

/**
 *
 * @author g1wshimu
 * Created: Nov 14, 2013
 */
public class UnusedIO {

    private static final String SEPARATOR = ":";
    
    /**
     * Given a line of the form: <br />
     * key:value <br />
     * Returns a Pair where the first element is key and the second element
     * is value. Returns null if the line is ill formed.
     * 
     * @param line
     * @return 
     */
    private static Pair<String, String> parse(String line) {
        int index = line.indexOf(SEPARATOR);
        if (index <= 0) {
            return null;
        }

        String key = line.substring(0, index);

        // Returns the empty String if given the length of the String
        String value = line.substring(index + 1);

        return new Pair<>(key, value);
    }

    /**
     * Save the content of all the text fields to a text file at the given url. 
     * Each line of the text file contains a key, an equal sign, and the
     * String contained in the text field pointed to by the key (null if the 
     * text field has no text).
     * 
     * @param url the URL of the file to save the text field data to.
     * @throws IOException if any exception is thrown during the write process
     */
    public static void save(String url, Map<String, ?> mapping) throws IOException {
        File file = new File(url);

        List<String> content;

        if (file.exists()) {
            content = Files.readLines(file, Charset.defaultCharset());
        } else {
            Files.createParentDirs(file);
            content = new ArrayList<>();
            System.err.println("No setting files were found, previous settings may be lost");
        }


        try (BufferedWriter writer = FileIO.getFileWriter(url, false)) {
            Set<String> keySet = new TreeSet<>(mapping.keySet());

            for (String s : content) {
                Pair<String, String> pair = parse(s);

                final String key;
                if ((pair != null) && keySet.contains(key = pair.getFirst())) {
                    // If we have the matching text field, update its value
                    writeKeyValuePair(writer, key, mapping.get(key));
                    
                    // We wrote the value, so remove the key
                    keySet.remove(key);

                } else {
                    // Otherwise, either the line does not have the valid format
                    // or we do not have the matching text field, 
                    // leave the content as it is
                    writer.write(s);
                    writer.newLine();
                }
            }

            // Write the remaining keys
            for (String k : keySet) {
                writeKeyValuePair(writer, k, mapping.get(k));
            }
        }
    }

    /**
     * Initializes all the text fields from the contents of the given text file. 
     * @param url the URL of the text file.
     * @throws FileNotFoundException if a text file at the given URL cannot
     * be found
     * @throws IOException if an exception is thrown while reading from the
     * file
     */
    public static Map<String, String> load(String url) throws IOException {
        List<String> content = Files.readLines(new File(url), Charset.defaultCharset());
        
        Map<String, String> map = new HashMap<>();
        for(String line: content) {
         Pair<String, String> pair = parse(line);

            if (pair != null) {
                map.put(pair.getFirst(), pair.getSecond());
            }
        }
        
        return map;
    }

    /**
     * Write the content of the TextField at the given key using the given 
     * BufferedWriter.
     * @param writer
     * @param key
     */
    private static void writeKeyValuePair(BufferedWriter writer, String key, Object value)
            throws IOException {
        writer.write(key);
        writer.write(SEPARATOR);
        if (value != null) {
            writer.write(value.toString());
        }
        writer.newLine();
    }
}
